import 'cnd.dart';
import 'cnd_operator.dart';
import 'cnds.dart';

/// 条件构建结果
class CndResult {
  /// WHERE子句（不包含WHERE关键字）
  final String whereClause;

  /// 参数列表
  final List<dynamic> parameters;

  /// 参数映射
  final Map<String, dynamic> parameterMap;

  const CndResult({
    required this.whereClause,
    required this.parameters,
    required this.parameterMap,
  });

  /// 是否有条件
  bool get hasCnds => whereClause.isNotEmpty;
}

/// 条件构建工具类
///
/// 提供基于Cnd对象的条件构建功能
/// 支持Cnd列表 + toMap()方式
class CndUtil {
  /// 根据Cnd列表和数据映射生成WHERE条件
  static CndResult buildCnd(
    List<Cnd> cndList,
    Map<String, dynamic> dataMap, [
    Map<String, String>? field2Col,
  ]) {
    final builder = Cnds();

    for (final cnd in cndList) {
      final colName = field2Col?[cnd.name] ?? cnd.name;
      final value = dataMap[cnd.name];

      if (cnd.shouldIgnore(value)) continue;

      // 根据操作符类型调用相应的builder方法
      switch (cnd.op) {
        case CndOperator.eq:
          builder.eq(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.ne:
          builder.ne(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.gt:
          builder.gt(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.ge:
          builder.ge(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.lt:
          builder.lt(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.le:
          builder.le(colName, value,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.like:
          builder.like(colName, value as String,
              tableAlias: cnd.tableAlias,
              ignoreNull: false,
              caseSensitive: true);
          break;
        case CndOperator.notLike:
          builder.notLike(colName, value as String,
              tableAlias: cnd.tableAlias,
              ignoreNull: false,
              caseSensitive: true);
          break;
        case CndOperator.isNull:
          builder.isNull(colName, tableAlias: cnd.tableAlias);
          break;
        case CndOperator.isNotNull:
          builder.isNotNull(colName, tableAlias: cnd.tableAlias);
          break;
        case CndOperator.in_:
          builder.in_(colName, value as Iterable,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.notIn:
          builder.notIn(colName, value as Iterable,
              tableAlias: cnd.tableAlias, ignoreNull: false);
          break;
        case CndOperator.between:
          final range = value as Range;
          builder.between(colName, range.start, range.end,
              tableAlias: cnd.tableAlias);
          break;
        case CndOperator.notBetween:
          final range = value as Range;
          builder.notBetween(colName, range.start, range.end,
              tableAlias: cnd.tableAlias);
          break;
      }
    }

    return builder.build();
  }
}
